import * as THREE from "three";
import * as d3 from "d3";

let objectMap: THREE.Object3D;
let loader = new THREE.FileLoader();
loader.load("/sceneJson/china.json", (data: any) => {
  let jsonData = JSON.parse(data);
  objectMap = initMap(jsonData);
});

function initMap(chinaJson: any) {
  const map = new THREE.Object3D();
  const projection = d3
    .geoMercator()
    .center([104.0, 37.5])
    .scale(80)
    .translate([0, 0]);

  chinaJson.features.forEach((element: any) => {
    // 创建3D省份对象
    const province = new THREE.Object3D();

    // 坐标数组
    const coordinates = element.geometry.coordinates;

    // 循环坐标数组
    coordinates.forEach((item: any) => {
      item.forEach((polygon: any) => {
        const shape = new THREE.Shape();
        const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff });
        const lineGeometry = new THREE.BufferGeometry();

        const vertices: THREE.Vector3[] = [];
        for (let i = 0; i < polygon.length; i++) {
          // @ts-ignore
          const [x, y] = projection(polygon[i]);
          if (i === 0) {
            shape.moveTo(x, -y);
          }
          shape.lineTo(x, -y);
          const vertex = new THREE.Vector3(x, -y, 4.01);
          vertices.push(vertex);
        }
        lineGeometry.setFromPoints(vertices);

        const extrudeSettings = {
          depth: 4,
          bevelEnabled: false,
        };

        const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);

        const material = new THREE.MeshBasicMaterial({
          color: "#02A1E2",
          transparent: true,
          opacity: 0.6,
        });

        const material1 = new THREE.MeshBasicMaterial({
          color: "#3480C4",
          transparent: true,
          opacity: 0.5,
        });

        const mesh = new THREE.Mesh(geometry, [material, material1]);
        const line = new THREE.Line(lineGeometry, lineMaterial);

        province.add(mesh);
        province.add(line);
      });
    });

    // 将geo的属性放到省份模型中
    province.userData.properties = element.properties;

    if (element.properties.contorid) {
      // @ts-ignore
      const [x, y] = projection(element.properties.contorid);
      province.userData.properties._centroid = [x, y];
    }
    map.add(province);
  });

  return map;
}

// 计算鼠标点击位置的二维向量
function calculateMousePosition(event: MouseEvent, container: HTMLElement) {
  return new THREE.Vector2(
    (event.offsetX / container.clientWidth) * 2 - 1,
    -(event.offsetY / container.clientHeight) * 2 + 1
  );
}

// 创建射线投射器
function createRaycaster(
  mousePosition: THREE.Vector2,
  camera: THREE.PerspectiveCamera
) {
  let raycaster = new THREE.Raycaster();
  raycaster.setFromCamera(mousePosition, camera);
  return raycaster;
}

// 获取射线与模型的交点
function getIntersectedObject(
  raycaster: THREE.Raycaster,
  group: THREE.Group | THREE.Scene
) {
  let intersects = raycaster.intersectObject(group, true);
  return intersects.length ? (intersects[0].object) : null;
}

export {
  objectMap,
  calculateMousePosition,
  createRaycaster,
  getIntersectedObject,
};
